const webpack = require('webpack')
const path = require('path')
const Dotenv = require('dotenv-webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin')
const { JSDOM } = require('jsdom')

module.exports = {
  mode: 'production',
  entry: {
    main: './src/index.tsx',
    inpage: './src/inpage.ts',
    background: './src/background.ts',
    contentscript: './src/content.ts',
    webapp: './src/webapp.tsx'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js', // Output will be inpage.js, background.js, and main.js
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'ts-loader'
        }
      },
      {
        test: /\.vanilla\.css$/i, // Targets only CSS files generated by vanilla-extract
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: require.resolve('css-loader'),
            options: {
              url: false
            }
          }
        ]
      },
      {
        test: /\.wasm$/,
        type: 'webassembly/async'
      }
    ]
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    fallback: {
      vm: require.resolve('vm-browserify'),
      stream: require.resolve('stream-browserify'),
      crypto: require.resolve('crypto-browserify'),
      zlib: require.resolve('browserify-zlib'),
      'process/browser': require.resolve('process/browser'),
      fs: false
    }
  },
  plugins: [
    new webpack.ProvidePlugin({
      Buffer: ['buffer', 'Buffer'],
      process: 'process/browser'
    }),
    function () {
      this.hooks.afterEnvironment.tap('JSDOM', () => {
        const { window } = new JSDOM('', {
          url: 'http://localhost'
        })

        global.window = window
        global.document = window.document
        global.HTMLElement = window.HTMLElement
        global.navigator = window.navigator
        global.customElements = window.customElements
        global.CSSStyleSheet = window.CSSStyleSheet
        global.localStorage = window.localStorage
      })
    },
    new Dotenv({
      path: './.env',
      systemvars: true
    }),
    new HtmlWebpackPlugin({
      chunks: ['main'],
      template: './src/index.html',
      filename: 'popup.html'
    }),
    new HtmlWebpackPlugin({
      chunks: ['webapp'],
      template: './src/webapp.html',
      filename: 'index.html'
    }),
    new CopyWebpackPlugin({
      patterns: [
        { from: 'src/manifest.json', to: 'manifest.json' },
        { from: 'src/assets/icon.png', to: 'icon.png' },
        { from: 'src/assets', to: 'assets' }
      ]
    }),
    new MiniCssExtractPlugin(),
    new VanillaExtractPlugin()
  ],
  devServer: {
    static: {
      directory: path.join(__dirname, 'src')
    },
    compress: true,
    port: 9000,
    hot: true
  },
  experiments: {
    asyncWebAssembly: true
  }
}
